<?php
/**
 * Classe astratta per la gestione delle Entity.
 * Questa classe in base alla dichiarazione della Entity e' in grado di istanziare
 * tutta la struttura di quest'ultima a partire dal tipo di dato fino ad arrivare
 * alle regole per ogni colonna mappata sul database.
 *
 * @author Damiano Ciarla
 * @version 2.0
 * @category lib/entity
 */
abstract class Entity
{
	private $_vars = array();
	private $tableName;
	private $serial = null;

	public function __construct($tableName)
	{
		$this->tableName = $tableName;
	}

	/**
	 * Mappatura sul DB di una variabile della entity
	 *
	 * @param string $varName Nome della variabile es: $userId = 'userId'
	 * @param string $dbColumnName Nome della colonna sul database
	 * @param string $type Tipo di dato es: EntityType::VARCHAR
	 * @param int $size Eventuale lunghezza del campo
	 * @param boolean $required Valore booleano per identificare se il campo è obbligatorio o meno
	 * @param boolean $serial Valore booleano per identificare se il campo è chiave primaria
	 * @param string $label Traduzione della stringa per i messaggi di errore per l'auto validazione
	 */

	protected function _addColumn($varName, $dbColumnName, $type, $size, $required, $serial = FALSE, $label = NULL)
	{
		$this->_vars[$varName] = array("DB_COLUMN" => $dbColumnName, "TYPE" => $type, "SIZE" => $size, "REQUIRED" => $required, "LABEL" => $label, "RULES" => array());

		if ($serial) // trovato un serial autoincrement
			$this->serial = array("VAR_NAME" => $varName, "DB_COLUMN" => $dbColumnName);
	}

	/**
	 * Aggiunge una regole esplicitata nel costruttore della Entity
	 *
	 * @param string $varName	Nome della variabile a cui applicare la regola
	 * @param string $rule		Nome della regola
	 * @param string $value		Condizione della regola
	 */

	protected function _addRule($varName, $rule, $value = null)
	{
		include_once BXD_INCLUDEPATH . 'lib/entity/Rule.php';

		$this->_vars[$varName]["RULES"][] = new Rule($rule, $value);
	}

	/**
	 * Restituisce l'array delle variabili e regole inizializzate nel costruttore
	 *
	 * @return array Array delle variabili
	 */

	public function _getVars()
	{
		return $this->_vars;
	}

	/**
	 * Restituisce il tipo della colonna sul database per il campo corrispondente
	 *
	 * @param String $col Nome della variabile CAMMELLATA
	 * @return String Tipo della relativa colonna mappata sul DATABASE
	 */

	public function _getColType($col)
	{
		return $this->_vars[$col]["TYPE"];
	}

	/**
	 * Restituisce il nome reale della colonna sul database
	 *
	 * @param String $col Nome della variabile CAMMELLATA
	 * @return String Nome della relativa colonna mappata sul DATABASE
	 */

	public function _getColName($col)
	{
		return $this->_vars[$col]["DB_COLUMN"];
	}

	/**
	 * Metodo che restituisce un array associativo con CHIAVE > DB_COLUMN e VALORE > Nome della variabile
	 *
	 * @return array Array con DB_COLUMN - Nome della variabile
	 */

	public function _getVarsFromColumn()
	{
		$newArray = array();

		foreach ($this->_vars as $key => $value)
			$newArray[$value["DB_COLUMN"]] = $key;

		return $newArray;
	}

	public function __get($name)
	{
		$methodName = "get" . ucfirst($name);

		if(method_exists($this, $methodName))
			return call_user_func_array(array($this, $methodName), array());
		else
			BXD::newException("EntityVarNotFound", "The variable " . $name . " is not defined in class " . get_class($this));

	}

	public function __set($name,  $value)
	{
		$methodName = "set" . ucfirst($name);

		if(method_exists($this, $methodName))
			return call_user_func_array(array($this, $methodName), array($value));
		else
			BXD::newException("EntityVarNotFound", "The variable " . $name . " is not defined in class " . get_class($this));
	}

	/**
	 * Ritorna il nome della tabella del DATABASE
	 *
	 * @return String Nome della tabella
	 */

	public function _getTableName()
	{
		return $this->tableName;
	}

	/**
	 * Ritorna il nome della chiave primaria. Il nome è quello presente sul DB e
	 * NON IL NOME DELLA VARIABILE CAMMELLATA
	 *
	 * @return string Nome della chiave primaria
	 */

	public function _getSerial($type = NULL)
	{
		if($this->serial !== NULL)
		{
			if($type == "DB_COLUMN" || $type == "VAR_NAME")
			{
				return $this->serial[$type];
			}
			else if($type === NULL)
			{
				return $this->serial;
			}
			else
			{
				return NULL;
			}
		}
		else
		{
			return NULL;
		}
	}
}
?>
